home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / chat / reflect.000 / reflect / 3.0b3 / ocp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  25.0 KB  |  824 lines

  1. /*
  2.  
  3. Copyright 1993, 1994, Cornell University
  4.  
  5. Cornell hereby grants permission to use, copy, modify, and distribute this program for any purpose 
  6. and without fee, provided that these copyright and permission notices appear on all copies and 
  7. supporting documentation, the name of Cornell not be used in advertising or publicity pertaining 
  8. to distribution of the program without specific prior permission, notice be given in supporting 
  9. documentation that copying and distribution is by permission of Cornell.  CORNELL MAKES NO 
  10. REPRESENTATIONS OR WARRANTEES, EXPRESS OR IMPLIED.  By way of example, but not limitation, 
  11. CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR 
  12. PURPOSE OR THAT THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, 
  13. TRADEMARKS, OR OTHER RIGHTS.  Cornell shall not be held liable for any liability with respect to 
  14. any claim by the user or any other party arising from use of the program.
  15.  
  16. This material is partially based on work sponsored by the National Science Foundation under Cooperative 
  17. Agreement No. NCR-9318337.  The government has certain rights in this material.
  18.  
  19. */
  20.  
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <varargs.h>
  25. #include <signal.h>
  26. #include <errno.h>
  27. #include <malloc.h>
  28. #include <sys/types.h>
  29. #include <sys/param.h>
  30. #include <sys/ioctl.h>
  31. #include <sys/socket.h>
  32. #include <sys/time.h>
  33.  
  34. #ifndef LINUX
  35. #include <sys/socketvar.h>
  36. #include <net/route.h>
  37. #endif
  38.  
  39. #include <net/if.h>
  40. #include <netinet/in.h>
  41.  
  42. #include "reflect.h"
  43. #include "refmon.h"
  44. #include "globals.h"
  45.  
  46. client *open_connection(vidptr,csock,type)
  47.    VideoPacketHeader   *vidptr;
  48.    struct sockaddr_in  *csock;
  49.    int                 type;
  50. {
  51.     client        *cltptr,*ctmp;
  52.     short         client_id,cnt;
  53.     struct timezone  tzp;
  54.     struct in_addr      in;
  55.  
  56.  
  57.  
  58.     switch (type)
  59.     {
  60.        case BCC_CLIENT:
  61.        case BCC_GCLIENT:
  62.       if (type == BCC_CLIENT)
  63.       {
  64.              dolog("BCC client at %s is opening connection\n", inet_ntoa(csock->sin_addr));
  65.              bcc_client_cnt++;
  66.       }
  67.           else
  68.       {
  69.              dolog("BCC general client at %s is opening connection\n", inet_ntoa(csock->sin_addr));
  70.              bcc_gclient_cnt++;
  71.       }
  72.           cltptr = (client *) get_client();
  73.           cltptr->clnt_addr.family = AF_INET;
  74.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  75.           cltptr->clnt_flags |= type; 
  76.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  77.  
  78.  
  79.       if (type == BCC_CLIENT)
  80.              strcpy(cltptr->clnt_config.name,"BCC CLIENT");
  81.           else
  82.              strcpy(cltptr->clnt_config.name,"BCC GCLIENT");
  83.  
  84.           cltptr->clnt_nptr = chead;
  85.           chead = cltptr;
  86.           return(cltptr);
  87.  
  88.        case BCC_SERVER:
  89.           dolog("BCC server at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  90.  
  91.           cltptr = (client *) get_client();
  92.           cltptr->clnt_addr.family = AF_INET;
  93.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  94.           cltptr->clnt_flags |= BCC_SERVER;
  95.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  96.           strcpy(cltptr->clnt_config.name,"BCC SERVER");
  97.  
  98.           cltptr->clnt_nptr = chead;
  99.           chead = cltptr;
  100.  
  101.           bcc_server_cnt++;
  102.  
  103.           open_connection(vidptr,(struct sockaddr_in *) &vidptr->routing.src,BCC_ORIGIN);
  104.           return(cltptr);
  105.  
  106.        case BCC_ORIGIN:  
  107.           dolog("BCC server's client at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  108.  
  109.           if ((client_id = get_client_id()) == -1)
  110.           {
  111.              dolog("maximum # of clients exceeded\n");
  112.              return(NULL);
  113.           }
  114.       
  115.           cltptr = (client *) get_client();
  116.           cltptr->clnt_addr.family = AF_INET;
  117.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  118.           cltptr->clnt_flags |= BCC_ORIGIN;
  119.           cltptr->clnt_id = client_id;
  120.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  121.       
  122.           cltptr->clnt_nptr = chead;
  123.           chead = cltptr;
  124.  
  125.           bcc_origin_cnt++;
  126.       
  127.           update_client(cltptr,vidptr,FALSE,FALSE);
  128.  
  129.           return(cltptr);
  130.  
  131.        case REF1_CLIENT:   
  132.           dolog("REF downstream client at %s is opening connection\n", inet_ntoa(csock->sin_addr));
  133.  
  134.           cltptr = (client *) get_client();
  135.           cltptr->clnt_addr.family = AF_INET;
  136.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  137.           cltptr->clnt_flags |= REF1_CLIENT; 
  138.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  139.           strcpy(cltptr->clnt_config.name,"Downsteam REF");
  140.  
  141.           cltptr->clnt_nptr = chead;
  142.           chead = cltptr;
  143.  
  144.           ref1_client_cnt++;
  145.  
  146.           return(cltptr);
  147.  
  148.        case REF1_SERVER:
  149.  
  150.           dolog("REF upstream server at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  151.  
  152.           cltptr = (client *) get_client();
  153.           cltptr->clnt_addr.family = AF_INET;
  154.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  155.           cltptr->clnt_flags |= REF1_SERVER;
  156.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  157.           strcpy(cltptr->clnt_config.name,"Upstream REF");
  158.  
  159.           cltptr->clnt_nptr = chead;
  160.           chead = cltptr;
  161.  
  162.           ref1_server_cnt++;
  163.  
  164.           open_connection(vidptr,(struct sockaddr_in *) &vidptr->routing.src,REF1_ORIGIN);
  165.           return(cltptr);
  166.  
  167.        case REF1_ORIGIN:   
  168.           dolog("REF upstream server's client at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  169.  
  170.           if ((client_id = get_client_id()) == -1)
  171.           {
  172.              dolog("maximum # of clients exceeded\n");
  173.              return(NULL);
  174.           }
  175.       
  176.           cltptr = (client *) get_client();
  177.           cltptr->clnt_addr.family = AF_INET;
  178.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  179.           cltptr->clnt_flags |= REF1_ORIGIN;
  180.           cltptr->clnt_id = client_id;
  181.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  182.       
  183.           cltptr->clnt_nptr = chead;
  184.           chead = cltptr;
  185.  
  186.           ref1_origin_cnt++;
  187.  
  188.           update_client(cltptr,vidptr,FALSE,FALSE);
  189.  
  190.           return(cltptr);
  191.  
  192.        case REF2_SERVER:   
  193.  
  194.           dolog("REF group server at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  195.  
  196.           cltptr = (client *) get_client();
  197.           cltptr->clnt_addr.family = AF_INET;
  198.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  199.           cltptr->clnt_flags |= REF2_SERVER;
  200.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  201.           strcpy(cltptr->clnt_config.name,"Group REF");
  202.  
  203.           cltptr->clnt_nptr = chead;
  204.           chead = cltptr;
  205.  
  206.           ref2_server_cnt++;
  207.  
  208.           open_connection(vidptr,(struct sockaddr_in *) &vidptr->routing.src,REF2_ORIGIN);
  209.           return(cltptr);
  210.  
  211.        case REF2_ORIGIN:
  212.  
  213.           dolog("REF group server's client at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  214.  
  215.           if ((client_id = get_client_id()) == -1)
  216.           {
  217.              dolog("maximum # of clients exceeded\n");
  218.              return(NULL);
  219.           }
  220.  
  221.           cltptr = (client *) get_client();
  222.           cltptr->clnt_addr.family = AF_INET;
  223.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  224.           cltptr->clnt_flags |= REF2_ORIGIN;
  225.           cltptr->clnt_id = client_id;
  226.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  227.  
  228.           cltptr->clnt_nptr = chead;
  229.           chead = cltptr;
  230.       
  231.           ref2_origin_cnt++;
  232.  
  233.           update_client(cltptr,vidptr,FALSE,FALSE);
  234.           return(cltptr);
  235.  
  236.        case REF3_SERVER:   
  237.  
  238.           dolog("REF unicast group server at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  239.  
  240.           cltptr = (client *) get_client();
  241.           cltptr->clnt_addr.family = AF_INET;
  242.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  243.           cltptr->clnt_flags |= REF3_SERVER;
  244.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  245.           strcpy(cltptr->clnt_config.name,"Group Uni REF");
  246.  
  247.           for (cnt=0; cnt<ref_ucast_cnt; cnt++)
  248.              if (ref_ucast_list[cnt] == csock->sin_addr.s_addr)
  249.              {
  250.                 cltptr->clnt_id = cnt;
  251.                 break;
  252.              } 
  253.  
  254.           cltptr->clnt_nptr = chead;
  255.           chead = cltptr;
  256.  
  257.           ref3_server_cnt++;
  258.  
  259.           return(cltptr);
  260.  
  261.        case REF3_ORIGIN:
  262.  
  263.           dolog("REF unicast group server's client at %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  264.  
  265.           if ((client_id = get_client_id()) == -1)
  266.           {
  267.              dolog("maximum # of clients exceeded\n");
  268.              return(NULL);
  269.           }
  270.  
  271.           cltptr = (client *) get_client();
  272.           cltptr->clnt_addr.family = AF_INET;
  273.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  274.           cltptr->clnt_flags |= REF3_ORIGIN;
  275.           cltptr->clnt_id = client_id;
  276.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  277.  
  278.           cltptr->clnt_nptr = chead;
  279.           chead = cltptr;
  280.       
  281.           ref3_origin_cnt++;
  282.  
  283.           update_client(cltptr,vidptr,FALSE,FALSE);
  284.           return(cltptr);
  285.  
  286.  
  287.        case CLIENT:
  288.           dolog("Client at source %s is opening a connection\n", inet_ntoa(csock->sin_addr));
  289.  
  290.           if (csock->sin_addr.s_addr != vidptr->routing.src.addr)
  291.           {
  292.              in.s_addr = vidptr->routing.src.addr;
  293.              dolog("Client's network address does not agree with protocol address %s\n",inet_ntoa(in));
  294.              return(NULL);
  295.           }
  296.  
  297.           if ((client_id = get_client_id()) == -1)
  298.           {
  299.              dolog("maximum # of clients exceeded\n");
  300.              return(NULL);
  301.           }
  302.       
  303.           cltptr = (client *) get_client();
  304.           cltptr->clnt_addr.family = AF_INET;
  305.           cltptr->clnt_addr.port = vidptr->routing.src.port;
  306.           cltptr->clnt_flags |= CLIENT;
  307.           cltptr->clnt_id = client_id;
  308.           cltptr->clnt_conf_id = vidptr->conferenceid;
  309.           bcopy(&csock->sin_addr,&cltptr->clnt_addr.addr,4);
  310.       
  311.           cltptr->clnt_nptr = chead;
  312.           chead = cltptr;
  313.  
  314.           client_cnt++;
  315.  
  316.       check_restricted_senders(vidptr);
  317.       
  318.           update_client(cltptr,vidptr,TRUE,TRUE);
  319.  
  320.       if (cltptr->clnt_config.sendMode)
  321.       {
  322.          if (++send_ccnt > maxsenders)
  323.          {
  324.         if (maxsenders != -1)
  325.         {
  326.                    dolog("maximum # of senders exceeded\n");
  327.                    write_msg(&cltptr->clnt_addr,kMessageType1,ms_buf);
  328.                    delete_client(cltptr);
  329.                    return(NULL);
  330.         }
  331.          }
  332.       }
  333.       else
  334.       {
  335.          if (++lurker_ccnt > maxlurkers)
  336.          {
  337.         if (maxlurkers != -1)
  338.         {
  339.                    dolog("maximum # of lurkers exceeded\n");
  340.                    write_msg(&cltptr->clnt_addr,kMessageType1,ml_buf);
  341.                    delete_client(cltptr);
  342.                    return(NULL);
  343.                 }
  344.          }
  345.       }
  346.  
  347.           if (client_cnt >= maxallowed)
  348.           {
  349.              write_msg(&cltptr->clnt_addr,kMessageType1,mp_buf);
  350.              delete_client(cltptr);
  351.              return(NULL);
  352.           }
  353.  
  354.           if (motd_len != 0)
  355.              write_msg(&cltptr->clnt_addr,kMessageType2,motd_buf);
  356.  
  357.           gettimeofday(&cltptr->clnt_tp, &tzp);
  358.           return(cltptr);
  359.     }
  360. }
  361.  
  362. void continue_connection(cltptr,vidptr)
  363.    client              *cltptr;
  364.    VideoPacketHeader   *vidptr;
  365. {
  366.     client        *ctmp;
  367.     char          *cptr;
  368.     unsigned long seqnum,diff;
  369.     short         type;
  370.     short         doslist;
  371.     unsigned char old_sendMode;
  372.  
  373.     cltptr->clnt_hdloop = 0;
  374.     cltptr->clnt_flags &= ~HOLD_DOWN;
  375.  
  376.     if (cltptr->clnt_flags & CLIENT)
  377.     {
  378.        cptr = ((char *)vidptr + HEADERLEN);
  379.        seqnum = ntohl(*((unsigned long *) (cptr + 2)));
  380.  
  381.        check_restricted_senders(vidptr);
  382.        
  383.        diff = seqnum - cltptr->clnt_config.seqNum;
  384.        if (diff > 0)
  385.        {
  386.           old_sendMode = cltptr->clnt_config.sendMode;
  387.           if (diff == 1)
  388.              update_client(cltptr,vidptr,TRUE,FALSE);
  389.           else
  390.              update_client(cltptr,vidptr,TRUE,TRUE);
  391.  
  392.           if (((old_sendMode == 0) && (cltptr->clnt_config.sendMode != 0)) ||
  393.               ((old_sendMode != 0) && (cltptr->clnt_config.sendMode == 0))) 
  394.       {
  395.          if (old_sendMode)
  396.          {
  397.                 send_ccnt--;
  398.         lurker_ccnt++;
  399.         dolog("Client %s is going from a sender to a lurker\n",cltptr->clnt_config.name);
  400.         if ((maxlurkers != -1) && (lurker_ccnt > maxlurkers))
  401.         {
  402.                    write_msg(&cltptr->clnt_addr,kMessageType1,ml_buf);
  403.                    delete_client(cltptr);
  404.         }
  405.          }
  406.          else
  407.          {
  408.                 send_ccnt++;
  409.         lurker_ccnt--;
  410.         dolog("Client %s is going from a lurker to a sender\n",cltptr->clnt_config.name);
  411.         if ((maxsenders != -1) && (send_ccnt > maxsenders))
  412.         {
  413.                    write_msg(&cltptr->clnt_addr,kMessageType1,ms_buf);
  414.                    delete_client(cltptr);
  415.         }
  416.          }
  417.      }
  418.        }
  419.  
  420.        if ((cltptr->clnt_stimer >= ACKOPEN) || (cltptr->clnt_config.flags & WANT_VERSION))
  421.        {
  422. #ifdef DEBUG
  423.           if (debug)
  424.              printf("ACK timeout sending open ack to %s\n",cltptr->clnt_config.name);
  425. #endif
  426.           write_cmsg(VERSION_NUM,cltptr);
  427.        }
  428.        return;
  429.     }
  430.  
  431.  
  432.     if (cltptr->clnt_flags & BCC_SERVER)
  433.     {
  434.        type = BCC_ORIGIN;
  435.        doslist = FALSE;
  436.     }
  437.     else
  438.     if (cltptr->clnt_flags & REF1_SERVER)
  439.     {
  440.        type = REF1_ORIGIN;
  441.        doslist = FALSE;
  442.     }
  443.     else
  444.     if (cltptr->clnt_flags & REF2_SERVER)
  445.     {
  446.        type = REF2_ORIGIN;
  447.        doslist = TRUE;
  448.     }
  449.     else
  450.     if (cltptr->clnt_flags & REF3_SERVER)
  451.     {
  452.        type = REF3_ORIGIN;
  453.        doslist = TRUE;
  454.     }
  455.     else
  456.        return;
  457.  
  458.  
  459.     if ((ctmp = find_client(vidptr->routing.src.addr)) != NULL)
  460.     {
  461.        ctmp->clnt_rtimer = 0;
  462.        cptr = ((char *)vidptr + HEADERLEN);
  463.        seqnum = ntohl(*((unsigned long *) (cptr + 2)));
  464.        
  465.        diff = seqnum - ctmp->clnt_config.seqNum;
  466.        if (diff == 1)
  467.           update_client(ctmp,vidptr,doslist,FALSE);
  468.        else
  469.           if (diff > 1)
  470.              update_client(ctmp,vidptr,doslist,TRUE);
  471.     }
  472.     else
  473.        if ((ctmp = open_connection(vidptr,(struct sockaddr_in *) &vidptr->routing.src,type)) != NULL)
  474.        {
  475.           if (type == REF3_ORIGIN)
  476.              ctmp->clnt_pptr = cltptr;
  477.        }
  478.  
  479.      
  480. }
  481.  
  482. void update_client(cltptr,vidptr,doslist,all)
  483.     client              *cltptr;
  484.     VideoPacketHeader   *vidptr;
  485.     short               doslist;
  486.     short               all;
  487. {
  488.     ClientInfo       *ciptr;
  489.     client           *ctmp;
  490.     slist            *stmp;
  491.     char             *cptr;
  492.  
  493.     char             name_len;
  494.     short            cnt;
  495.     struct in_addr   in;
  496.  
  497.  
  498.     cptr = ((char *) vidptr + HEADERLEN);
  499.  
  500.     cltptr->clnt_config.clientCount = ntohs(*((short *)cptr));
  501.     cptr += sizeof(short);
  502.  
  503.     if (cltptr->clnt_config.clientCount > 20)
  504.        return;
  505.  
  506.     dolog("updating client %s client count %d   seq %ld\n",
  507.           cltptr->clnt_config.name,cltptr->clnt_config.clientCount,cltptr->clnt_config.seqNum);
  508.  
  509.     cltptr->clnt_config.seqNum = ntohl(*((unsigned long *)cptr));
  510.  
  511.     cptr += sizeof(unsigned long);
  512.  
  513.     name_len = *cptr++; 
  514.     if (name_len > 19)
  515.     {
  516.        dolog("bogus name length %d\n",name_len);
  517.        name_len = 19;
  518.     }
  519.  
  520.     for (cnt = 0; cnt < name_len; cnt++)
  521.     {
  522.        cltptr->clnt_config.name[cnt] = cptr[cnt];
  523.  
  524.        if (cltptr->clnt_config.name[cnt] == '\n')
  525.           cltptr->clnt_config.name[cnt] = ' ';
  526.  
  527.        if (cltptr->clnt_config.name[cnt] == '\r')
  528.           cltptr->clnt_config.name[cnt] = ' ';
  529.     }       
  530.  
  531.     cltptr->clnt_config.name[name_len] = 0;
  532.  
  533.     cptr += 19;
  534.  
  535.     cltptr->clnt_config.sendMode = *cptr++;
  536.     cltptr->clnt_config.recvMode = *cptr++;
  537.     cltptr->clnt_config.flags = *cptr++;
  538.  
  539.     if ((cltptr->clnt_config.version = *cptr++) < VERSION1)
  540.        all = TRUE;
  541.  
  542.     /* delete this client from the other client's send list                                     */
  543.  
  544.     if (doslist == FALSE)
  545.        return;
  546.  
  547.     if (all)
  548.     {
  549.        ctmp = chead;
  550.        while (ctmp != NULL)
  551.        {
  552.           ctmp->clnt_vlist = unlink_slist(ctmp->clnt_vlist,cltptr);
  553.           ctmp->clnt_alist = unlink_slist(ctmp->clnt_alist,cltptr);
  554.           ctmp->clnt_xlist = unlink_slist(ctmp->clnt_xlist,cltptr);
  555.           ctmp = ctmp->clnt_nptr;
  556.        }
  557.     }
  558.  
  559.     /*
  560.     ctmp = chead;
  561.     while (ctmp != NULL)
  562.     {
  563.        stmp = ctmp->clnt_vlist;
  564.        cnt = 0;
  565.        while (stmp != NULL)
  566.        {
  567.           cnt++;
  568.           if (stmp->snd_client == cltptr)
  569.              dolog("SLIST IS DAMAGED\n");
  570.           stmp = stmp->snd_nptr;
  571.        }
  572.        dolog("%s's slist count %d\n",ctmp->clnt_config.name,cnt);
  573.        ctmp = ctmp->clnt_nptr;
  574.     }
  575.     */
  576.  
  577.     ciptr = (ClientInfo *) (cptr);
  578.  
  579.     for (cnt = 0; cnt < cltptr->clnt_config.clientCount; cnt++)
  580.     {
  581.        if (all)
  582.        {
  583.           if ((ctmp = find_client(ciptr->clientIP)) == NULL)
  584.           {
  585.              if (find_vat_client(ciptr->clientIP) == NULL)
  586.          {
  587.                 in.s_addr = ciptr->clientIP;
  588.                 dolog("%s wants to update %s but client not found\n",cltptr->clnt_config.name,inet_ntoa(in));
  589.                 write_close(cltptr,ciptr->clientIP);
  590.          }
  591.              ciptr++;
  592.              continue;
  593.           }
  594.  
  595.           if (ciptr->IWillRecv)
  596.           {
  597.              if (cltptr->clnt_config.version >= VERSION5)
  598.                 dolog("%s wants to receive video from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  599.              else
  600.                 dolog("%s wants to receive audio and video from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  601.  
  602.              stmp = (slist *) get_slist();
  603.              stmp->snd_nptr = ctmp->clnt_vlist;
  604.              ctmp->clnt_vlist = stmp;
  605.              stmp->snd_client = cltptr;
  606.  
  607.              if (cltptr->clnt_config.version  < VERSION5)
  608.              {
  609.                 stmp = (slist *) get_slist();
  610.                 stmp->snd_nptr = ctmp->clnt_alist;
  611.                 ctmp->clnt_alist = stmp;
  612.                 stmp->snd_client = cltptr;
  613.              }
  614.  
  615.           }
  616.  
  617.           if (ciptr->flags & IWillRecAudio)
  618.           {
  619.              dolog("%s wants to receive audio from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  620.   
  621.              stmp = (slist *) get_slist();
  622.              stmp->snd_nptr = ctmp->clnt_alist;
  623.              ctmp->clnt_alist = stmp;
  624.              stmp->snd_client = cltptr;
  625.           }
  626.  
  627.           if (ciptr->aux != 0)
  628.           {
  629.              dolog("%s wants to receive aux data from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  630.   
  631.              stmp = (slist *) get_slist();
  632.              stmp->snd_nptr = ctmp->clnt_xlist;
  633.              ctmp->clnt_xlist = stmp;
  634.              stmp->snd_client = cltptr;
  635.              stmp->snd_auxmask = ciptr->aux;
  636.           }
  637.        }        
  638.        else
  639.           if (ciptr->flags & (UPDATE_VIDEO | UPDATE_AUDIO | UPDATE_AUXDATA))
  640.           {
  641.              if ((ctmp = find_client(ciptr->clientIP)) == NULL)
  642.              {
  643.                 if (find_vat_client(ciptr->clientIP) == NULL)
  644.         {
  645.                    in.s_addr = ciptr->clientIP;
  646.                    dolog("%s wants to update client at %s but client not found\n",cltptr->clnt_config.name,inet_ntoa(in));
  647.                    write_close(cltptr,ciptr->clientIP);
  648.         }
  649.                 ciptr++;
  650.                 continue;
  651.              }
  652.  
  653.              if (ciptr->flags & UPDATE_VIDEO)
  654.              {
  655.                 if (ciptr->IWillRecv)
  656.                 {
  657.                    if (cltptr->clnt_config.version  >= VERSION5)
  658.                       dolog("%s wants to receive video from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  659.                    else
  660.                       dolog("%s wants to receive video and audio from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  661.  
  662.                    /* make sure the client isn't already in the list  */
  663.                    stmp = ctmp->clnt_vlist;
  664.                    while (stmp != NULL)
  665.                    {
  666.                       if (stmp->snd_client == cltptr)
  667.                          break;
  668.                       stmp = stmp->snd_nptr;
  669.                    }
  670.  
  671.                    if (stmp == NULL)
  672.                    {
  673.                       stmp = (slist *) get_slist();
  674.                       stmp->snd_nptr = ctmp->clnt_vlist;
  675.                       ctmp->clnt_vlist = stmp;
  676.                       stmp->snd_client = cltptr;
  677.  
  678.                       if (cltptr->clnt_config.version  < VERSION5)
  679.                       {
  680.                          stmp = (slist *) get_slist();
  681.                          stmp->snd_nptr = ctmp->clnt_alist;
  682.                          ctmp->clnt_alist = stmp;
  683.                          stmp->snd_client = cltptr;
  684.                       }
  685.                    }
  686.                 }
  687.                 else
  688.                 {
  689.                    if (cltptr->clnt_config.version  >= VERSION5)
  690.                    {
  691.                       dolog("%s no longer wants to receive video from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  692.                       ctmp->clnt_vlist = unlink_slist(ctmp->clnt_vlist,cltptr);
  693.                    }
  694.                    else
  695.                    {
  696.                       dolog("%s no longer wants to receive video or audio from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  697.                       ctmp->clnt_vlist = unlink_slist(ctmp->clnt_vlist,cltptr);
  698.                       ctmp->clnt_alist = unlink_slist(ctmp->clnt_alist,cltptr);
  699.                    }
  700.                 }
  701.              }
  702.  
  703.              if (ciptr->flags & UPDATE_AUDIO)
  704.              {
  705.                 if (ciptr->flags & IWillRecAudio)
  706.                 {
  707.                    dolog("%s wants to receive audio from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  708.  
  709.                    /* make sure the client isn't already in the list  */
  710.                    stmp = ctmp->clnt_alist;
  711.                    while (stmp != NULL)
  712.                    {
  713.                       if (stmp->snd_client == cltptr)
  714.                          break;
  715.                       stmp = stmp->snd_nptr;
  716.                    }
  717.    
  718.                    if (stmp == NULL)
  719.                    {
  720.                       stmp = (slist *) get_slist();
  721.                       stmp->snd_nptr = ctmp->clnt_alist;
  722.                       ctmp->clnt_alist = stmp;
  723.                       stmp->snd_client = cltptr;
  724.                    }
  725.                 }
  726.                 else
  727.                 {
  728.                    dolog("%s no longer wants to receive audio from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  729.                    ctmp->clnt_alist = unlink_slist(ctmp->clnt_alist,cltptr);
  730.                 }
  731.              }
  732.    
  733.              if (ciptr->flags & UPDATE_AUXDATA)
  734.              {
  735.                 if (ciptr->aux != 0)
  736.                 {
  737.                    dolog("%s wants to receive aux data from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  738.    
  739.                    /* make sure the client isn't already in the list  */
  740.                    stmp = ctmp->clnt_xlist;
  741.                    while (stmp != NULL)
  742.                    {
  743.                       if (stmp->snd_client == cltptr)
  744.                          break;
  745.                       stmp = stmp->snd_nptr;
  746.                    }
  747.    
  748.                    if (stmp == NULL)
  749.                    {
  750.                       stmp = (slist *) get_slist();
  751.                       stmp->snd_nptr = ctmp->clnt_xlist;
  752.                       ctmp->clnt_xlist = stmp;
  753.                       stmp->snd_client = cltptr;
  754.                    }
  755.                    stmp->snd_auxmask = ciptr->aux;
  756.                 }
  757.                 else
  758.                 {
  759.                    dolog("%s no longer wants to aux data from %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
  760.                    ctmp->clnt_xlist = unlink_slist(ctmp->clnt_xlist,cltptr);
  761.                 }
  762.              }
  763.           }
  764.        ciptr++;
  765.     }
  766. }
  767.  
  768.  
  769. void check_restricted_senders(vidptr)
  770.     VideoPacketHeader   *vidptr;
  771. {
  772.     OCExtraHeader    *oceh;
  773.     TMapHeader       *tptr;
  774.     char             *cptr;
  775.     short            size,cnt;
  776.  
  777.  
  778.     /* 
  779.        if the high bit is set on the conference_id then don't allow clients to "send",
  780.        unless the ids match, but otherwise allow them to remain connnected as lurkers
  781.     */
  782.  
  783.     if (conference_id & 0x8000) 
  784.     {
  785.         if (ntohs(vidptr->conferenceid) == conference_id)
  786.        return;
  787.     }
  788.     else
  789.        if (local_senders)
  790.           return;
  791.  
  792.     for (cnt=0; cnt < admit_cnt; cnt++)
  793.        if (admit_senders[cnt] == vidptr->routing.src.addr)
  794.           return;
  795.  
  796.     cptr = ((char *) vidptr + HEADERLEN);
  797.     cnt = ntohs(*((short *)cptr));
  798.  
  799.     cptr += 26;                                        /* index to sendMode in the OpenContinueData */
  800.     *cptr = 0;                                         /* not capable of sending video              */
  801.  
  802.     cptr += 2;                                         /* index to flags in the OpenCOntinueData    */
  803.     *cptr &= ~AUDIO_CAPABLE;                           /* indicate not audio capable          */
  804.  
  805.  
  806.     /*
  807.        figure out if there is an AUX Data advertisement field in this OCP, if so clear out
  808.        the count, so that no one will as for this client's AUX Data.
  809.     */
  810.  
  811.     size = HEADERLEN + OCDLEN + (cnt * CILEN);
  812.  
  813.     if (size == ntohs(vidptr->len))
  814.        return;
  815.  
  816.     oceh = (OCExtraHeader *) ((char *) vidptr + size);
  817.     if (oceh->dataType != kAuxTMAdvExtraType)
  818.        return;
  819.  
  820.     tptr = (TMapHeader *) ((char *) oceh + sizeof(OCExtraHeader));
  821.  
  822.     tptr->count = 0;
  823. }
  824.